﻿using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace GetZipPwd
{
    public partial class FrmMain : Form
    {
        RangeStrMaker strMaker;
        public FrmMain()
        {
            InitializeComponent();
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            BtnTest_Click(sender, e);
            if (string.IsNullOrEmpty(lbPath.Text))
            {
                textBox1.Text = "没有选择文件";
                return;
            }
            lbStartTime.Text = "开始:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            Application.DoEvents();
            string pwd = TestPwd(lbPath.Text);
            if (pwd != null)
                textBox1.Text = "密码是:" + pwd;
            else
                textBox1.Text = "没有找到密码";
            lbFinishTime.Text = "结束" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }

        private string TestPwd(String zipFileName)
        {
            strMaker = new RangeStrMaker() { chars = getPwdChar(), StrWidth = (int)nudLow.Value };
            using (ZipFile file = new ZipFile(zipFileName))
            {
                //对于每一种宽度
                for (decimal i = nudLow.Value; i <= nudHigh.Value; i++)
                { 
                    //初始化密钥生成器
                    lbCurrentWidth.Text = "当前位数:" + i;
                    Application.DoEvents();
                    strMaker.StrWidth = (int)i;
                    strMaker.Init();
                    if (TestEachPwd(file, strMaker.GetCurrent()))
                        return strMaker.GetCurrent();
                    string tempPwd;
                    while ((tempPwd = strMaker.GetNext()) != null)
                    {
                        if (TestEachPwd(file, tempPwd))
                            return tempPwd;
                    }

                }
            }
            return null;
        }

        private bool TestEachPwd(ZipFile file, String pwd)
        {
            file.Password = pwd;
            return file.TestArchive(true);
        }

        private void BtnOpenFile_Click(object sender, EventArgs e)
        {
            if (ofdOpen.ShowDialog() == DialogResult.OK)
            {
                lbPath.Text = ofdOpen.FileName;
            }
        }

        private void BtnTest_Click(object sender, EventArgs e)
        {
            if (nudLow.Value > nudHigh.Value)
            {
                lbReport.Text = "密码位数的最小值应该小于最大值";
                return;
            }
            List<char> allpwdChar = getPwdChar();
            if (allpwdChar.Count == 0)
            {
                lbReport.Text = "密码备选字符集合是空的";
                return;
            }
            lbReport.Text = "密码备选字符:" + new string(getPwdChar().ToArray());

            lbReport.Text += string.Format("共{0}个,长度范围{1}~{2},", getPwdChar().Count, nudLow.Value, nudHigh.Value);
            double count = 0;
            for (decimal i = nudLow.Value; i <= nudHigh.Value; i++)
            {
                count += Math.Pow(allpwdChar.Count, Convert.ToDouble(i));
            }
            lbReport.Text += string.Format("需要测试{0}次", count);

        }
        private List<char> getPwdChar()
        {
            StringBuilder pwdChar = new StringBuilder();
            if (ckbNum.Checked)
                pwdChar.Append("0123456789");
            if (ckbLower.Checked)
                pwdChar.Append("abcdefghijklmnopqrstuvwxyz");
            if (ckbUpper.Checked)
                pwdChar.Append("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
            if (ckbOther.Checked)
                pwdChar.Append(txtOther.Text.Trim());
            char[] chars = pwdChar.ToString().ToCharArray();
            return chars.Distinct().ToList();
        }
    }
}
